﻿using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.Dependency;
using Abp.Domain.Entities;
using Abp.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Batman.Cms.Core.Services
{
    public class BaseReader<T> : ApplicationService, ITransientDependency where T : Entity<string>
    {
        public IRepository<T, string> Repository { get; set; }

        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="page"></param>
        /// <param name="expression">委托，交给控制器执行，懒得写那么多的类</param>
        /// <returns></returns>
        public async Task<PagedResultDto<TResult>> GetPageAsync<TResult>(PagedResultRequestDto page, Func<IQueryable<T>, IQueryable<TResult>> expression = null)
            where TResult : new()
        {
            var repository = IocManager.Instance.Resolve<IRepository<T, string>>();

            var query = repository.GetAll().AsNoTracking();

            if (expression != null)
            {
                var newQuery = expression.Invoke(query);

                var total = await newQuery.CountAsync();
                var items = await newQuery.Skip(page.SkipCount).Take(page.MaxResultCount).ToListAsync();

                return new PagedResultDto<TResult>(total, items);
            }

            return new PagedResultDto<TResult>();
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        public List<TResult> Query<TResult>(Func<IQueryable<T>, IQueryable<TResult>> expression)
        {
            var repository = IocManager.Instance.Resolve<IRepository<T, string>>();

            var query = repository.GetAll().AsNoTracking();

            var newQuery = expression.Invoke(query);

            return newQuery.ToList();
        }
    }
}
